

import java.util.*;

public class PractiseMethod {
    public static void main(String[] args) {


        getAge();
        getAge(23);
        long fib = fibonacci(6);
        System.out.println(fib);

        long fac = factorial(3);
        System.out.println(fac);

        methodOverRide();

        displayObjectClass(new Object());
        displayObjectClass(new ArrayList<>());
        displayObjectClass(new HashMap<>());

        int[] nums = {1, 0, 2, 1, 3, 7};
        printNum(nums);
        findNum(nums, 1);

        printNum2(nums);

        testLabel();
        testLabel2();


        System.out.println(Car.lamborghini);

        testfor1();
        testfor2();

        printList1();
        printList2();
        printList3();


        Integer[] numbers = {3, 2, 1, 3, 4};
        Integer sum = sumvarargs(numbers);
        System.out.println(sum);



        sumvarargs("计算总和   ",numbers);

        printJiuJiu();


        InvertedTriangle();
        Parallelogram();
        Rect();
    }

    /**
     * 方法重载
     * 定义：方法名相同，参数类型或个数不同，返回值可以相同也可以不同，方法的修饰符可以相同也可以不同
     * <p>
     * 使用方法重载的好处：
     * 1.同一个操作动作，使用一个方法名，传参和返回值不同，这样便于记忆方法名称，避免同一个操作多个名字，难记忆。
     * 2.增强代码灵活性和复用性，对同一类操作，后续增加方法时和已有方法名一样。
     * 3.符合自然语言习惯和编程直觉。
     * <p>
     * 是不是必须使用方法重载
     * 1.不是，这个只是一个编程习惯，约定俗成的规定。是一种编程思想和习惯。实际上对系统而言，后台对相同名字的方法都是按不同方法来处理的。
     */
    public static void getAge() {
        System.out.println("年龄为：18");
    }

    public static void getAge(int age) {
        System.out.println("年龄为：" + age);
    }

    /**
     * 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233，377，610，……
     * <p>
     * 特别指出：第0项是0，第1项是第一个1。
     * <p>
     * 这个数列从第三项开始，每一项都等于前两项之和。
     */
    public static long fibonacci(long index) {
        if (index == 0 || index == 1) {
            return index;
        } else {
            return fibonacci(index - 1) + fibonacci(index - 2);
        }

    }

    /**
     * 一个正整数的阶乘（英语：factorial）是所有小于及等于该数的正整数的积，并且有0的阶乘为1。自然数n的阶乘写作n!。
     * <p>
     * 亦即n!=1×2×3×...×n。阶乘亦可以递归方式定义：0!=1，n!=(n-1)!×n
     */
    public static long factorial(long number) {
        if (number == 0) {
            return 1;
        } else {
            return number * factorial(number - 1);
        }

    }

    /**
     * 方法覆盖：
     * 1.必须有继承的存在
     * 2.方法覆盖发生在子类的方法上
     * 3.子类的方法和父类一样（返回值类型属于父类的返回值类型，参数类型，个数，顺序），但是实现的内容不一样。
     * 4.子类的方法访问修饰符不能比父类更严格。例如，父类方法是public，子类覆盖的方法不能是private或protected ；父类方法是protected，子类覆盖的方法不能是private。
     * 5.子类不能抛出比父类更宽泛的异常。例如：父类方法声明抛出IOException，子类覆盖的方法不能抛出Exception。但可以抛出IOException的子类异常或者不抛出异常。
     * <p>
     * 方法覆盖的作用和意义：
     * 1.实现多态
     * 2.代码复用与定制
     * 3.符合现实世界建模
     * <p>
     * 方法覆盖的时候最好用一个@Override注解,虽然注解不是必须，但是有助于编译器检查。
     */

    public static void methodOverRide() {
        Animal animal = new Dog();
        animal.makeSound();

        Animal animal2 = new Animal();
        animal2.makeSound();
    }

    /**
     * instanceof 是 Java 的一个二元操作符，类似于 ==，>，< 等操作符。
     * <p>
     * instanceof 是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回 boolean 的数据类型
     */

    public static void displayObjectClass(Object o) {
        if (o instanceof Vector)
            System.out.println("对象是 java.util.Vector 类的实例");
        else if (o instanceof ArrayList)
            System.out.println("对象是 java.util.ArrayList 类的实例");
        else
            System.out.println("对象是 " + o.getClass() + " 类的实例");
    }

    /**
     * break 直接跳出循环
     */

    public static void printNum(int[] nums) {
        for (int i : nums) {
            if (i == 0) {
                break;
            }
            System.out.println(i);
        }

    }

    /**
     * break 延申出一道题
     * 找数组里的元素，找到就退出
     */
    public static void findNum(int[] nums, int target) {
        int i = 0;
        boolean isfund = false;

        for (; i < nums.length; i++) {
            if (nums[i] == target) {
                isfund = true;
                break;
            }

        }

        if (isfund) {
            System.out.println(target + "在数组中的位置是" + i);
        } else {
            System.out.println(target + "没在数组中");
        }
    }

    /**
     * continue 跳过当前循环并开始下一次循环
     */

    public static void printNum2(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 2) {
                continue; // 当 nums[i] 为 2 时，跳过本次循环剩余内容，进入下一次循环
            }
            System.out.println(nums[i]);
        }
    }


    /**
     * 标签
     * 标签（Label）是一种用于标识代码块的标识符，通常与循环语句（如for、while、do-while）和分支语句（如if-else、switch）一起使用。
     * <p>
     * 标签的语法形式为在代码块之前加上标识符并以冒号结尾
     */
    public static void testLabel() {
        outerLoop:
        for (int i = 0; i < 3; i++) {
            innerLoop:
            for (int j = 0; j < 3; j++) {
                if (j == 1 && i == 1) { //break的作用是遇到i=1，j=1的时候，就立马不执行outerLoop了。外部循环停止。
                    break outerLoop;
                }
                System.out.println("i 的值为 " + i + "    j 的值为：" + j);
            }
        }

    }

    /**
     * 用continue测试标签的使用
     */
    public static void testLabel2() {
        System.out.println("-------------------------------------------");
        outerLoop:
        for (int i = 0; i < 3; i++) {
            innerLoop:
            for (int j = 0; j < 3; j++) {
                if (j == 1 && i == 1) { //continue的作用是遇到i=1，j=1的时候，就跳过当前循环执行下次循环
                    continue outerLoop;
                }
                System.out.println("i 的值为 " + i + "    j 的值为：" + j);
            }
        }

    }


    /**
     * 两种for循环-1
     */

    public static void testfor1() {
        int[] nums = {3, 1, 2, 4};
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums[i]);
        }
    }

    /**
     * 两种for循环-2
     */

    public static void testfor2() {
        System.out.println("----------testfor2-----------");
        int[] nums = {3, 1, 2, 4};
        for (int i : nums) {
            System.out.println(i);
        }
    }


    /**
     * 从for循环延申list的3种遍历方式---1
     */

    public static void printList1() {
        System.out.println("---------printList1------------");
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(2);
        list.add(1);

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }


    /**
     * 从for循环延申list的3种遍历方式---2
     */

    public static void printList2() {
        System.out.println("---------printList2------------");
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(2);
        list.add(1);

        for (Integer i : list) {
            System.out.println(i);
        }
    }

    /**
     * 从for循环延申list的3种遍历方式---3
     */

    public static void printList3() {
        System.out.println("---------printList3------------");
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(2);
        list.add(1);

        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    /**
     * Java1.5提供了一个叫varargs的新功能，就是可变长度的参数。
     * <p>
     * "Varargs"是"variable number of arguments"的意思。有时候也被简单的称为"variable arguments"
     * 定义实参个数可变的方法：只要在一个形参的"类型"与"参数名"之间加上三个连续的"."（即"..."，英文里的句中省略号），就可以让它和不确定个实参相匹配。
     */
    public static int sumvarargs(Integer... intArrays) {
        System.out.println("---------sumvarargs------------");
        int sum = 0;
        for (int i = 0; i < intArrays.length; i++) {
            sum = sum + intArrays[i];//编译器会将可变参数隐式处理为一个数组，在方法内部可以像操作数组一样使用可变参数.注意传值也只能传数组。
        }
        return sum;
    }

    /**
     * 注意：可变参数必须放在所有参数的最后
     * 举例如下：
     */
    public static int sumvarargs(String str,Integer... intArrays) {
        System.out.println("---------sumvarargs------------");
        int sum = 0;

        for (int i = 0; i < intArrays.length; i++) {
            sum = sum + intArrays[i];//编译器会将可变参数隐式处理为一个数组，在方法内部可以像操作数组一样使用可变参数.注意传值也只能传数组。
        }
        System.out.println(str+sum);
        return sum;
    }


    /**
     * 打印9*9乘法表
     */

    public static void printJiuJiu(){
        System.out.println("---------printJiuJiu------------");
        for(int i=1;i<10;i++){
            for(int j=1;j<=i;j++){
                int m=i*j;
                System.out.print(j+"*"+i+"="+m+ "   ");
            }
            System.out.println("");


        }

    }
    /**
     * 打印倒立的三角形
     */

    public static void InvertedTriangle(){
        System.out.println("---------InvertedTriangle------------");
        for(int i=1;i<=4;i++){
            if(i==1){
                for(int j=0;j<7;j++){
                    System.out.print("*");
                }
                System.out.println();
            }
            if(i==2){
                System.out.print(" ");
                for(int j=0;j<5;j++){
                    System.out.print("*");
                }
                System.out.println();

            }
            if(i==3){
                System.out.print("  ");
                for(int j=0;j<3;j++){
                    System.out.print("*");
                }
                System.out.println();
            }
            if(i==4){
                System.out.print("   ");
                for(int j=0;j<1;j++){
                    System.out.print("*");
                }
                System.out.println();
            }
        }
    }

    /**
     * 打印平行四边形
     */
    public static void Parallelogram(){
        System.out.println("---------Parallelogram------------");
        for(int i=1;i<=5;i++){
            if(i==1){
                System.out.print("    ");
                for(int j=1;j<=5;j++){
                    System.out.print("*");
                }
                System.out.println("");
            }


            if(i==2){
                System.out.print("   ");
                for(int j=1;j<=5;j++){
                    System.out.print("*");
                }
                System.out.println("");
            }

            if(i==3){
                System.out.print("  ");
                for(int j=1;j<=5;j++){
                    System.out.print("*");
                }
                System.out.println("");
            }

            if(i==4){
                System.out.print(" ");
                for(int j=1;j<=5;j++){
                    System.out.print("*");
                }
                System.out.println("");
            }
            if(i==4){
                System.out.print("");
                for(int j=1;j<=5;j++){
                    System.out.print("*");
                }
                System.out.println("");
            }

        }

    }

    /**
     * 打印矩形
     */

    public static void Rect(){
        System.out.println("---------Rect------------");


        for(int i=1;i<=5;i++){
            for(int j=1;j<=5;j++){
                System.out.print("*");
            }
            System.out.println("");
        }
    }



}
